Enforce program stack limits on function parameters. Previously, a function's parameter list did not count against its stack size limit. Bug: 278113033 Test: SkQP (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:e3ab186a075a174f44692bf6a31165f30f6b7ded) Merged-In: If49dce98f3155f3144a766c26b5a3a39401ce1b2 Change-Id: If49dce98f3155f3144a766c26b5a3a39401ce1b2 
diff --git a/gn/sksl_tests.gni b/gn/sksl_tests.gni index d4c4ad4..fdb0b91 100644 --- a/gn/sksl_tests.gni +++ b/gn/sksl_tests.gni 
@@ -146,6 +146,7 @@  "/sksl/errors/PrivateTypes.rts",  "/sksl/errors/PrivateVariables.rts",  "/sksl/errors/ProgramTooLarge_Globals.rts", + "/sksl/errors/ProgramTooLarge_Parameters.rts",  "/sksl/errors/ProgramTooLarge_Stack.rts",  "/sksl/errors/PrototypeInFuncBody.rts",  "/sksl/errors/RedeclareBasicType.rts", 
diff --git a/resources/sksl/errors/ProgramTooLarge_Parameters.rts b/resources/sksl/errors/ProgramTooLarge_Parameters.rts new file mode 100644 index 0000000..cced977 --- /dev/null +++ b/resources/sksl/errors/ProgramTooLarge_Parameters.rts 
@@ -0,0 +1,14 @@ +struct S { + half4 ah4[1]; + half ah[99999]; + half4 h4; + half h; +}; + +void func(int small, + S big_chungus, + S no_report /*we don't need to report overflows past the first*/) {} + +/*%%* +variable 'big_chungus' exceeds the stack size limit +*%%*/ 
diff --git a/src/sksl/ir/SkSLFunctionDefinition.cpp b/src/sksl/ir/SkSLFunctionDefinition.cpp index 3c7c3d1..5daee59 100644 --- a/src/sksl/ir/SkSLFunctionDefinition.cpp +++ b/src/sksl/ir/SkSLFunctionDefinition.cpp 
@@ -21,6 +21,8 @@  #include "src/sksl/transform/SkSLProgramWriter.h"    #include <forward_list> +#include <string_view> +#include <vector>    namespace SkSL {   @@ -80,7 +82,27 @@  FunctionSet* referencedBuiltinFunctions)  : fContext(context)  , fFunction(function) - , fReferencedBuiltinFunctions(referencedBuiltinFunctions) {} + , fReferencedBuiltinFunctions(referencedBuiltinFunctions) { + // Function parameters count as local variables. + for (const Variable* var : function.parameters()) { + this->addLocalVariable(var, function.fLine); + } + } + + void addLocalVariable(const Variable* var, int line) { + // We count the number of slots used, but don't consider the precision of the base type. + // In practice, this reflects what GPUs actually do pretty well. (i.e., RelaxedPrecision + // math doesn't mean your variable takes less space.) We also don't attempt to reclaim + // slots at the end of a Block. + size_t prevSlotsUsed = fSlotsUsed; + fSlotsUsed = SkSafeMath::Add(fSlotsUsed, var->type().slotCount()); + // To avoid overzealous error reporting, only trigger the error at the first + // place where the stack limit is exceeded. + if (prevSlotsUsed < kVariableSlotLimit && fSlotsUsed >= kVariableSlotLimit) { + fContext.fErrors->error(line, "variable '" + std::string(var->name()) + + "' exceeds the stack size limit"); + } + }    ~Finalizer() override {  SkASSERT(fBreakableLevel == 0); @@ -144,21 +166,8 @@  bool visitStatement(Statement& stmt) override {  switch (stmt.kind()) {  case Statement::Kind::kVarDeclaration: { - // We count the number of slots used, but don't consider the precision of the - // base type. In practice, this reflects what GPUs really do pretty well. - // (i.e., RelaxedPrecision math doesn't mean your variable takes less space.) - // We also don't attempt to reclaim slots at the end of a Block. - size_t prevSlotsUsed = fSlotsUsed; - fSlotsUsed = SkSafeMath::Add( - fSlotsUsed, stmt.as<VarDeclaration>().var().type().slotCount()); - // To avoid overzealous error reporting, only trigger the error at the first - // place where the stack limit is exceeded. - if (prevSlotsUsed < kVariableSlotLimit && fSlotsUsed >= kVariableSlotLimit) { - fContext.fErrors->error( - stmt.fLine, - "variable '" + std::string(stmt.as<VarDeclaration>().var().name()) + - "' exceeds the stack size limit"); - } + const Variable* var = &stmt.as<VarDeclaration>().var(); + this->addLocalVariable(var, stmt.fLine);  break;  }  case Statement::Kind::kReturn: { 
diff --git a/tests/sksl/errors/ProgramTooLarge_Parameters.glsl b/tests/sksl/errors/ProgramTooLarge_Parameters.glsl new file mode 100644 index 0000000..d92c325 --- /dev/null +++ b/tests/sksl/errors/ProgramTooLarge_Parameters.glsl 
@@ -0,0 +1,6 @@ +### Compilation failed: + +error: 10: variable 'big_chungus' exceeds the stack size limit + S no_report /*we don't need to report overflows past the first*/) {} + ^^ +1 error